﻿#include "CommonType.h"
#include <QHostAddress>
#include <QNetworkInterface>

QList<double> idxU;
QList<double> bbU;
QList<double> idxI;
QList<double> bbI;
double g_szU[3];//测量到的数字电压
double g_szI[3];//测量到的数字电流
double g_lvU[3];//测量到的模拟电压
double g_lvI[3];//测量到的模拟电流

//相电压转线电压相关常量定义
#define RADIAN  0.01745329

Rect     SymComA  = {-0.5, 0.8660254};                                    //a
Rect     SymComA2 = {-0.5,-0.8660254};                                    //a*a

//相电压转线电压常量定义完毕


//ok=true,转化成功;ok=false,转化失败
double s2d(QString s,bool *ok)
{
    double d = s.toDouble(ok);
    return d;
}

float s2f(QString s)
{
    return s.toFloat();
}

QString i2s(int i)
{
    QString s;
    s.sprintf("%d",i);
    return s;
}

QString u2s(unsigned int u)
{
    QString s;
    s.sprintf("%u",u);
    return s;
}

QString i3s(int i)
{
    QString s;
    s.sprintf("%03d",i);
    return s;
}

//ok=true,转化成功;ok=false,转化失败
double s2i(QString s,bool *ok)
{
    int i=s.toInt(ok);
    return i;
}

//float f要转换的数；int fraction保留几位小数
QString f2s(float f,int fraction)
{
    QString s;
    char format[100];
    sprintf(format,"%%.%df",fraction);
    s.sprintf(format,f);
    return s;
}

//double d要转换的数；int fraction保留几位小数
QString d2s(double d,int fraction)
{
    QString s;
    char format[100];
    sprintf(format,"%%.%df",fraction);
    s.sprintf(format,d);
    return s;
}

QString d2sl(double d,int strlen)
{
    QString d_str;
    int sTi=int(d);
    if(sTi >= 0)
    {
        int len=QString::number(sTi).length();
        //()<<"d2s"<<d<<fraction<<sTi<<len;
        if(len<= strlen)
        {
            d_str= QString("%1").arg(d,0,'f',strlen-len);
        }else{
            d_str= QString("%1").arg(d,0,'f',0);
        }
     //qDebug()<<"result"<<d_str;
    }else{
        float mun;
        mun=qAbs(d);
        int sTi2=int(mun);
         int len=QString::number(sTi2).length();
        if(len<= strlen)
        {
            d_str= QString("%1").arg(d,0,'f',strlen-len);
        }else{
            d_str= QString("%1").arg(d,0,'f',0);
        }
    }
    return d_str;
}


//字符串中的数字与单位（如：12Hz→12，Hz）
QString splitNum_Unit(QString inStr,QString &strUnit)
{
    int p=inStr.length();
    for(int i=p-1;i>=0;i--)
    {
        if(inStr[i] < '0' || inStr[i] > '9')
            p=i;
        else
            break;
    }
    strUnit=inStr.mid(p);
    return inStr.left(p);
}

QString ByteArray2HexString(QByteArray &ba)
{

    QString s;
    QString sb="";
    for (int i = 0; i < ba.size(); ++i)
    {
        s.sprintf("%02X",(unsigned char)ba.at(i));
        sb += s + " ";
    }

    //qDebug()<<ba.toHex();
    return sb;
}

void MySleep(int msec)
{
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

void getLangFromXml()
{
    QFile file0( "d:\\file.txt" );
    file0.open( QIODevice::WriteOnly | QIODevice::Text);
    QTextStream streamw( &file0 );

    QFile file( "d:\\English.ts" );
    if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
        QTextStream stream( &file );
        QString line;
        while ( !stream.atEnd() ) {
            line = stream.readLine(); // 不包括“/n”的一行文本
            if(line.indexOf("<source>")>=0)
            {
                QString str=getSubStr(line,"<source>","</source>");
                streamw<<str<<"\n";
            }

        }
        file.close();
    }
    file0.close();

}

void setLangToXml()
{
    QFile file0( "d:\\en.ts" );
    file0.open( QIODevice::WriteOnly | QIODevice::Text);
    QTextStream streamw( &file0 );

    QFile file1( "d:\\English.ts" );
    file1.open( QIODevice::ReadOnly | QIODevice::Text );
    QTextStream stream1( &file1 );

    QFile file2( "d:\\Book2.txt" );
    file2.open( QIODevice::ReadOnly | QIODevice::Text );
    QTextStream stream2( &file2 );

    QString line1,line2,en="";
    line2 = stream2.readLine();
    QStringList sl=line2.split('\t');
    while ( !stream1.atEnd() )
    {
        line1 = stream1.readLine(); // 不包括“/n”的一行文本
        if(line1.indexOf("<source>")>=0)
        {
            streamw<<line1<<"\n";
            QString str=getSubStr(line1,"<source>","</source>");
            qDebug()<<str<<sl[0];
            if(str == sl[0])
            {
                en=sl[1];
                line2 = stream2.readLine();
                sl=line2.split('\t');
            }
            else
                en="";
            streamw<<"        <translation type=\"unfinished\">"<<en<<"</translation>\n";

        }
        else if(line1.indexOf("<translation")>=0)
            ;
        else
            streamw<<line1<<"\n";

    }
    file1.close();
    file2.close();

    file0.close();

}

//功率因素转换为电压和电流之间的夹角
double glys2xj(QString glys)
{
    if(glys=="1")
        return 0;
    else if(glys=="0.5C")
        return 60;
    else if(glys=="0.5L")
        return 300;
    else if(glys=="0.8C")
        return 36.87;
    else if(glys=="0.8L")
        return 323.13;
   else if(glys=="0.25C")
        return 75.522;
    else if(glys=="0.25L")
        return 284.478;
    else if(glys=="0.866C")
        return 30;
    else if(glys=="0.866L")
        return 330;
    else
        return -1;
}

/*
 * 误差化整函数
 * yz 待化正的误差， jd精度等级
 **/
double wchz(double yz, double jd)
{
    double yzZ = yz;
    if (yz < 0)
        yzZ = yz * -1.0;

    double hz = 0.0; //化整后的值

    //化整间距
    double dJJ = jd / 10.0;

    //原值/化整间距
    double dYz1 = yzZ / dJJ;

    //取出小数部分
    int iZs = (int)dYz1; //整数部分
    double iXs = dYz1 - (double)iZs; //小数部分

    //分情况判断
    if (iXs < 0.5)
        hz = iZs;
    else if (iXs > 0.5)
        hz = iZs + 1;
    else //等于0.5，整数部分为偶数时不变，奇数时+1
    {
        if (iZs % 2 == 0)
            hz = iZs;
        else
            hz = iZs + 1;
    }

    hz = hz * dJJ;
    if (yz < 0)
        hz *= -1.0;
    return hz;
}

bool writeInit(QString group,QString user_key, QString user_value)
{
    QString path=QApplication::applicationFilePath().replace(".exe",".ini");
    if(path.isEmpty() || user_key.isEmpty())
    {
        return false;
    }
    else
    {
        //创建配置文件操作对象
        QSettings *config = new QSettings(path, QSettings::IniFormat);

        //将信息写入配置文件
        config->beginGroup(group);
        config->setValue(user_key, user_value);
        config->endGroup();

        return true;
    }
}

bool readInit(QString group, QString user_key, QString &user_value)
{
    QString path=QApplication::applicationFilePath().replace(".exe",".ini");
    user_value = QString("");
    if(path.isEmpty() || user_key.isEmpty())
    {
        return false;
    }
    else
    {
        //创建配置文件操作对象
        QSettings *config = new QSettings(path, QSettings::IniFormat);

        //读取用户配置信息
        user_value = config->value(group + QString("/") + user_key).toString();

        return true;
    }
}

QString getCompileDate()
{
    QDate buildDate = QLocale( QLocale::English ).toDate( QString( __DATE__ ).replace( "  ", " " ), "MMM dd yyyy");
    return buildDate.toString("yyyy-MM-dd");// + " " + QString(__TIME__);
}

//从strFrom中取出一个由头尾包围的子串，不包含头strBegin、尾strEnd
//头、尾中只要有一个找不到，就返回""
QString getSubStr(QString strFrom,QString strBegin,QString strEnd)
{
    int b=strFrom.indexOf(strBegin);
    int e=strFrom.indexOf(strEnd,b);
    qDebug()<<"getSubStr:b,e"<<b<<e;
    if(b>=0 && e>0)
    {
        int len=strBegin.length();
        QString str=strFrom.mid(b+len,e-b-len);
        qDebug()<<str;
        return str;
    }

    qDebug()<<"getSubStr: no found sub string";
    return "";
}

//获取头前的子字符串
QString getSubStr(QString strFrom,QString strBegin)
{
    int b = strFrom.indexOf(strBegin);
    if(b>=0)
    {
        QString strV = strFrom.mid(0,b);
        return strV;
    }
    return "";
}

int bytesToInt(QByteArray bytes)
{
    int addr = bytes[0] & 0x000000FF;
    addr |= ((bytes[1] << 8) & 0x0000FF00);
    addr |= ((bytes[2] << 16) & 0x00FF0000);
    addr |= ((bytes[3] << 24) & 0xFF000000);
    return addr;
}

QByteArray  intToByte(int number)
{
    QByteArray abyte0;
    abyte0.resize(4);
    abyte0[0] = (uchar)  (0x000000ff & number);
    abyte0[1] = (uchar) ((0x0000ff00 & number) >> 8);
    abyte0[2] = (uchar) ((0x00ff0000 & number) >> 16);
    abyte0[3] = (uchar) ((0xff000000 & number) >> 24);
    return abyte0;
}

float bytesToFloat(QByteArray bytes)
{
    float addr;
    memcpy(&addr,bytes.data(),4);

    return addr;
}

QByteArray  floatToByte(float number)
{
    QByteArray bytes;
    bytes.resize(4);
    memcpy(bytes.data(),&number,4);
    return bytes;
}


//拷贝文件：
bool copyFileToPath(QString fromFile ,QString toFile, bool coverFileIfExist)
{
    toFile.replace("\\","/");
    if (fromFile == toFile){
        return true;
    }
    if (!QFile::exists(fromFile)){
        return false;
    }
    QDir *createfile     = new QDir;
    bool exist = createfile->exists(toFile);
    if (exist){
        if(coverFileIfExist){
            createfile->remove(toFile);
        }
    }//end if

    if(!QFile::copy(fromFile, toFile))
    {
        return false;
    }
    return true;
}

//拷贝文件夹：
bool copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
    QDir sourceDir(fromDir);
    QDir targetDir(toDir);
    if(!targetDir.exists()){    /**< 如果目标目录不存在，则进行创建 */
        if(!targetDir.mkdir(targetDir.absolutePath()))
            return false;
    }

    QFileInfoList fileInfoList = sourceDir.entryInfoList();
    foreach(QFileInfo fileInfo, fileInfoList){
        if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
            continue;

        if(fileInfo.isDir()){    /**< 当为目录时，递归的进行copy */
            if(!copyDirectoryFiles(fileInfo.filePath(),
                targetDir.filePath(fileInfo.fileName()),
                coverFileIfExist))
                return false;
        }
        else{            /**< 当允许覆盖操作时，将旧文件进行删除操作 */
            if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
                targetDir.remove(fileInfo.fileName());
            }

            /// 进行文件copy
            if(!QFile::copy(fileInfo.filePath(),
                targetDir.filePath(fileInfo.fileName()))){
                    return false;
            }
        }
    }
    return true;
}

//删除文件夹里符合条件的文件（包含子文件夹内容）
//QString strBegin 删除条件（这里是指以strBegin开头的文件）
//返回值：删除的文件数量
int DeleteFileInDir(const QString dirPath,QString strBegin)
{
    QDir dir(dirPath);
    int result = 0;
    foreach (QFileInfo fileInfo, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot))
    {
        QString strName = fileInfo.fileName();
        if (fileInfo.isDir())
        {
            QString str = dirPath + "/" + strName + "/";
            result += DeleteFileInDir(str,strBegin);
        }
        else
        {
            if(strName.startsWith(strBegin))
            {
                QFile::remove(dirPath + "/" + strName);
                result++;
            }
        }
    }
    return result;
}


/*
 *得到当前表格中选中行的行号
 *返回-1表示没有选中行
 *仅适用于单选表格
 */
int GetSelectedRow(QTableWidget *table)
{
    QList<QTableWidgetSelectionRange> ranges=table->selectedRanges();
    for(int i=0;i<ranges.count();i++)
    {
        int topRow=ranges.at(i).topRow();
        int bottomRow=ranges.at(i).bottomRow();
        for(int j=topRow;j<=bottomRow;j++)
        {
            qDebug()<<"selectRow"<<j;

            return j;
        }
    }

    return -1;
}
/*
 *得到当前表格某个单元格的值
 */
QString getCellValue(QTableWidget *table,int r, int c)
{
    QString v;
    QTableWidgetItem *item=table->item(r,c);
    if(item != NULL)
        v=item->text();
    else
        v="";
    return v;
}
/*
 *设置表格某个单元格的值
 *bool bOk 是否合格，不合格的要用红字显示
 */
void setCellValue(QTableWidget *table,int r, int c, QString v, bool bOk)
{
    QTableWidgetItem *item=table->item(r,c);
    if(item != NULL)
        item->setText(v);
    else
        table->setItem(r,c,new QTableWidgetItem(v));

    item=table->item(r,c);
    if(!bOk)
        item->setForeground(Qt::red);
    else
        item->setForeground(Qt::black);
}
//日志系统
QTextEdit *ctLog;
QTextStream cout(stdout, QIODevice::WriteOnly);
void openLog(QTextEdit *txtLog)
{
    qInstallMessageHandler(customMessageHandler); //注册MsgHandler回调函数
    ctLog=txtLog;
}

void closeLog()
{
    qInstallMessageHandler(0); //取消注册MsgHandler回调函数
}

//void customMessageHandler(QtMsgType type, const QMessageLogContext &context,const char *msg)
void customMessageHandler(QtMsgType type, const QMessageLogContext &context,const QString &msg)
{
    if(type == QtDebugMsg)
    {
        QString txtMessage;
        txtMessage = QString("%1").arg(msg);
        cout <<txtMessage<<endl;//必须加endl才能输出到控制台

        //保存输出相关信息到指定文件
        QFileInfo fileInfo("Log.txt");
        //---获取文件大小（字节）
        qint64 size = fileInfo.size();

        QFile outputFile("Log.txt");
        if(size < 2 * 1024 * 1024)
            outputFile.open(QIODevice::WriteOnly | QIODevice::Append);
        else
        {
            QFile::remove("Log0.txt");
            QFile::copy("Log.txt","Log0.txt");
            outputFile.open(QIODevice::WriteOnly);
        }

        QTextStream textStream(&outputFile);
        textStream << QDateTime::currentDateTime().toString("[yyyy-MM-dd HH:mm:ss]");
        textStream << txtMessage << endl;

        if(ctLog != NULL)
            ctLog->append(txtMessage);
    }
}

//必须在show()之后调用才起作用
void centerWin(QWidget *w)
{
    QRect deskrect = QApplication::desktop()->availableGeometry();
    QRect framesize = w->frameGeometry();
    int x=(deskrect.width()-framesize.width())/2;
    int y=(deskrect.height()-framesize.height())/2;
    w->move(x,y);
    //qDebug()<<w->frameGeometry()<<w->geometry();
}

QString getHostIpAddress()
{
    QString strIpAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // 获取第一个本主机的IPv4地址
    int nListSize = ipAddressesList.size();
    for (int i = 0; i < nListSize; ++i)
    {
           if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
               ipAddressesList.at(i).toIPv4Address()) {
               strIpAddress = ipAddressesList.at(i).toString();
               if(strIpAddress.startsWith("192.168.1."))
                    break;
           }
     }
     // 如果没有找到，则以本地IP地址为IP
     if (strIpAddress.isEmpty())
        strIpAddress = QHostAddress(QHostAddress::LocalHost).toString();
     return strIpAddress;
}

//获取屏幕缩放比例（适用于高分辨率屏）
/*float geScaleFactor()
{
    float dpiX, scaleFactor;
    HDC screen = GetDC(0);
    dpiX = static_cast<float>(GetDeviceCaps(screen, LOGPIXELSX));
    ReleaseDC(0, screen);

    scaleFactor = dpiX / 96.0f; // this is same as devicePixelRatio
    return scaleFactor;
}*/

//相电压转线电压相关函数定义

//ST_ZEROCPS  ZeroCps;
/******************************************************************************/
/*Function   : RectAdd  RectMult                                        */
/*Description: Addition & Multiply for Rect component                      */
/*Input      : @a, first Rect data                                         */
/*             @b, second Rect data                                        */
/*Output     : add result/multiply result                                     */
/*Log        : 复数的加减                                                     */
/******************************************************************************/

Rect RectAdd(Rect a, Rect b)
{
    Rect addrslt;
    addrslt.re = a.re + b.re;
    addrslt.im = a.im + b.im;
    return addrslt;
}
Rect RectSub(Rect a, Rect b)
{
    Rect subrslt;
    subrslt.re = a.re - b.re;
    subrslt.im = a.im - b.im;
    return subrslt;
}
Rect RectMult(Rect a, Rect b)
{
    Rect mulrslt;
    mulrslt.re = a.re * b.re - a.im * b.im;
    mulrslt.im = a.re * b.im + a.im * b.re;
    return mulrslt;
}
Rect RectDiv(Rect a, Rect b)
{
    Rect dvdrslt;
    dvdrslt.re = (a.re * b.re + a.im * b.im)/(b.re * b.re + b.im * b.im);
    dvdrslt.im = (a.im * b.re - a.re * b.im)/(b.re * b.re + b.im * b.im);
    return dvdrslt;
}
//极坐标系转换成直角坐标系
Rect ConvertToRect(Polar smpst)
{
    Rect mulrslt;
    mulrslt.re = smpst.mag*cos(smpst.ang*RADIAN);
    mulrslt.im = smpst.mag*sin(smpst.ang*RADIAN);
    return mulrslt;
}
//直角坐标系转换成极坐标系
Polar ConvertToPolar(Rect mulrslt)
{
    Polar simprslt;
    simprslt.mag = sqrt(mulrslt.re*mulrslt.re + mulrslt.im*mulrslt.im);
    simprslt.ang = atan2(mulrslt.im,mulrslt.re)/RADIAN;
    return simprslt;
}
//转换成序分量
void ConvertToSeq(ST_SEQ * pSEQ)
{

    pSEQ->A.rectvalue = ConvertToRect(pSEQ->A.polarvalue);
    pSEQ->B.rectvalue = ConvertToRect(pSEQ->B.polarvalue);
    pSEQ->C.rectvalue = ConvertToRect(pSEQ->C.polarvalue);

    pSEQ->Pos.rectvalue = RectAdd(RectAdd(RectMult(SymComA,pSEQ->B.rectvalue), RectMult(SymComA2,pSEQ->C.rectvalue)), pSEQ->A.rectvalue);
    pSEQ->Neg.rectvalue = RectAdd(RectAdd(RectMult(SymComA2,pSEQ->B.rectvalue), RectMult(SymComA,pSEQ->C.rectvalue)), pSEQ->A.rectvalue);
    pSEQ->Zero.rectvalue = RectAdd(RectAdd(pSEQ->B.rectvalue, pSEQ->C.rectvalue), pSEQ->A.rectvalue);
    pSEQ->Pos.rectvalue.re = pSEQ->Pos.rectvalue.re/3;
    pSEQ->Pos.rectvalue.im = pSEQ->Pos.rectvalue.im/3;
    pSEQ->Neg.rectvalue.re = pSEQ->Neg.rectvalue.re/3;
    pSEQ->Neg.rectvalue.im = pSEQ->Neg.rectvalue.im/3;
    pSEQ->Zero.rectvalue.re = pSEQ->Zero.rectvalue.re/3;
    pSEQ->Zero.rectvalue.im = pSEQ->Zero.rectvalue.im/3;

    //电压正负零序的单数形式
    pSEQ->Pos.polarvalue = ConvertToPolar(pSEQ->Pos.rectvalue);
    pSEQ->Neg.polarvalue = ConvertToPolar(pSEQ->Neg.rectvalue);
    pSEQ->Zero.polarvalue = ConvertToPolar(pSEQ->Zero.rectvalue);


}
//转换成相分量
void ConvertToDrt(ST_SEQ * pSEQ)
{
      pSEQ->Pos.rectvalue = ConvertToRect(pSEQ->Pos.polarvalue);
    pSEQ->Neg.rectvalue = ConvertToRect(pSEQ->Neg.polarvalue);
    pSEQ->Zero.rectvalue = ConvertToRect(pSEQ->Zero.polarvalue);

    pSEQ->A.rectvalue = RectAdd(RectAdd(pSEQ->Neg.rectvalue, pSEQ->Zero.rectvalue),pSEQ->Pos.rectvalue);
    pSEQ->B.rectvalue = RectAdd(RectAdd(RectMult(SymComA2,pSEQ->Pos.rectvalue), RectMult(SymComA,pSEQ->Neg.rectvalue)), pSEQ->Zero.rectvalue);
    pSEQ->C.rectvalue = RectAdd(RectAdd(RectMult(SymComA,pSEQ->Pos.rectvalue), RectMult(SymComA2,pSEQ->Neg.rectvalue)), pSEQ->Zero.rectvalue);

    //电压正负零序的单数形式
    pSEQ->A.polarvalue = ConvertToPolar(pSEQ->A.rectvalue);
    pSEQ->B.polarvalue = ConvertToPolar(pSEQ->B.rectvalue);
    pSEQ->C.polarvalue = ConvertToPolar(pSEQ->C.rectvalue);

}
//相转线
void ConvertToLV(ST_SEQ * pUSeq, ST_SEQ *pLSeq)
{
      pLSeq->A.rectvalue = RectSub(pUSeq->A.rectvalue, pUSeq->B.rectvalue);
      pLSeq->B.rectvalue = RectSub(pUSeq->B.rectvalue, pUSeq->C.rectvalue);
      pLSeq->C.rectvalue = RectSub(pUSeq->C.rectvalue, pUSeq->A.rectvalue);

      pLSeq->A.polarvalue = ConvertToPolar(pLSeq->A.rectvalue);
      pLSeq->B.polarvalue = ConvertToPolar(pLSeq->B.rectvalue);
      pLSeq->C.polarvalue = ConvertToPolar(pLSeq->C.rectvalue);
}

//相电压转线电压函数定义完毕

int getRangeV(double d)
{
    if(d<58)
        return 0;
    else if(d<101)
        return 1;
    else if(d<221)
        return 2;
    else
        return 3;
}

int getRangeA(double d)
{
    if(d<1.1)
        return 0;
    else
        return 1;
}

int getVolRange(QString Vol)
{
    int vol_i;
    vol_i=0;
    if(Vol.indexOf('V'))
        Vol=Vol.remove('V');
    float f_v;
    f_v=Vol.toFloat();

    return getRangeV(f_v);
}

int getCurRange(QString Cur)
{
    int cur_i;
    cur_i=0;
    if(Cur.indexOf('A'))
        Cur=Cur.remove('A');
    float f_c;
    f_c=Cur.toFloat();

    return getRangeA(f_c);
}
